from django.http import JsonResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.authentication import SessionAuthentication
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiParameter
from drf_spectacular.types import OpenApiTypes


class CsrfExemptSessionAuthentication(SessionAuthentication):
    """Session认证，但豁免CSRF验证"""
    def enforce_csrf(self, request):
        return  # 不执行CSRF验证


def success_response(data=None, message='操作成功'):
    """成功响应"""
    return JsonResponse({
        'code': 200,
        'message': message,
        'data': data
    })


def error_response(message='操作失败', code=400):
    """错误响应"""
    return JsonResponse({
        'code': code,
        'message': message,
        'data': None
    })


@extend_schema(
    summary="用户登录",
    description="用户通过用户名和密码进行登录认证",
    auth=[],  # 登录接口不需要认证
    request={
        "application/json": {
            "type": "object",
            "required": ["username", "password"],
            "properties": {
                "username": {
                    "type": "string",
                    "description": "用户名，用于登录认证",
                    "example": "admin"
                },
                "password": {
                    "type": "string",
                    "description": "登录密码，将会进行加密验证",
                    "format": "password",
                    "example": "admin123"
                }
            },
            "example": {
                "username": "admin",
                "password": "admin123"
            }
        }
    },
    responses={
        200: OpenApiResponse(
            description="登录成功，返回用户信息。\n\n**认证凭证说明**：\n- 认证凭证通过 HTTP Cookie 中的 `sessionid` 自动设置\n- 响应头 `Set-Cookie` 示例：`sessionid=abc123; HttpOnly; Path=/`\n- 后续请求会自动携带此 Cookie 完成认证\n- Cookie 有效期默认为浏览器会话期间",
            response={
                "type": "object",
                "properties": {
                    "code": {"type": "integer", "example": 200},
                    "message": {"type": "string", "example": "登录成功"},
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {"type": "integer", "example": 1},
                            "username": {"type": "string", "example": "admin"},
                            "email": {"type": "string", "example": "admin@example.com"},
                            "is_staff": {"type": "boolean", "example": True},
                            "is_superuser": {"type": "boolean", "example": True}
                        }
                    }
                }
            }
        ),
        401: OpenApiResponse(description="用户名或密码错误"),
        400: OpenApiResponse(description="请求参数错误"),
    },
    tags=["用户认证"],
    methods=["POST"]
)
@api_view(['POST'])
@authentication_classes([CsrfExemptSessionAuthentication])  # 使用豁免CSRF的Session认证
@permission_classes([AllowAny])  # 允许所有用户访问，不需要认证
def login_view(request):
    """
    用户登录接口
    
    功能说明：
        - 用户通过用户名和密码进行登录认证
        - 登录成功后会自动创建会话，保持登录状态
    
    请求参数：
        username (str): 用户名，必填
        password (str): 密码，必填
    
    返回数据：
        {
            'code': 200,
            'message': '登录成功',
            'data': {
                'id': 用户ID,
                'username': 用户名,
                'email': 邮箱,
                'is_staff': 是否管理员,
                'is_superuser': 是否超级管理员
            }
        }
    
    错误码：
        400: 请求参数错误
        401: 用户名或密码错误
        500: 服务器错误
    """
    try:
        # 使用 DRF 的 request.data，不要使用 json.loads(request.body)
        username = request.data.get('username')
        password = request.data.get('password')
        
        if not username or not password:
            return error_response('用户名和密码不能为空')
        
        # 认证用户
        user = authenticate(request, username=username, password=password)
        
        if user is not None:
            # 登录成功
            login(request, user)
            return success_response({
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'is_staff': user.is_staff,
                'is_superuser': user.is_superuser
            }, '登录成功')
        else:
            return error_response('用户名或密码错误', 401)
            
    except Exception as e:
        return error_response(f'登录失败: {str(e)}', 500)


@extend_schema(
    summary="用户登出",
    description="退出当前用户的登录状态，清除会话信息",
    responses={
        200: OpenApiResponse(
            description="登出成功",
            response={
                "type": "object",
                "properties": {
                    "code": {"type": "integer", "example": 200},
                    "message": {"type": "string", "example": "登出成功"},
                    "data": {"type": "null"}
                }
            }
        ),
        500: OpenApiResponse(description="服务器错误"),
    },
    tags=["用户认证"],
    methods=["POST"]
)
@api_view(['POST'])
@authentication_classes([CsrfExemptSessionAuthentication])  # 使用豁免CSRF的Session认证
def logout_view(request):
    """
    用户登出接口
    
    功能说明：
        - 退出当前用户的登录状态
        - 清除服务器端的会话信息
    
    请求参数：
        无
    
    返回数据：
        {
            'code': 200,
            'message': '登出成功',
            'data': null
        }
    
    错误码：
        500: 服务器错误
    """
    try:
        logout(request)
        return success_response(message='登出成功')
    except Exception as e:
        return error_response(f'登出失败: {str(e)}', 500)


@extend_schema(
    summary="获取用户信息",
    description="获取当前已登录用户的详细信息，包括基本资料和权限信息",
    responses={
        200: OpenApiResponse(
            description="获取成功，返回用户详细信息",
            response={
                "type": "object",
                "properties": {
                    "code": {"type": "integer", "example": 200},
                    "message": {"type": "string", "example": "操作成功"},
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {"type": "integer", "description": "用户唯一标识ID", "example": 1},
                            "username": {"type": "string", "description": "用户名", "example": "admin"},
                            "email": {"type": "string", "description": "邮箱地址", "example": "admin@example.com"},
                            "first_name": {"type": "string", "description": "姓名-名", "example": "三"},
                            "last_name": {"type": "string", "description": "姓名-姓", "example": "张"},
                            "is_staff": {"type": "boolean", "description": "是否为管理员", "example": True},
                            "is_superuser": {"type": "boolean", "description": "是否为超级管理员", "example": True},
                            "date_joined": {"type": "string", "description": "注册时间", "example": "2024-01-01 10:00:00"},
                            "last_login": {"type": "string", "description": "最后一次登录时间", "example": "2024-01-15 14:30:00"},
                        }
                    }
                }
            }
        ),
        401: OpenApiResponse(description="用户未登录，请先登录"),
    },
    tags=["用户认证"],
    methods=["GET"]
)
@api_view(['GET'])
def info_view(request):
    """
    获取当前用户信息接口
    
    功能说明：
        - 获取当前已登录用户的详细信息
        - 包括用户名、邮箱、姓名、权限信息等
    
    请求参数：
        无
    
    返回数据：
        {
            'code': 200,
            'message': '操作成功',
            'data': {
                'id': 用户ID,
                'username': 用户名,
                'email': 邮箱,
                'first_name': 名,
                'last_name': 姓,
                'is_staff': 是否管理员,
                'is_superuser': 是否超级管理员,
                'date_joined': 注册时间,
                'last_login': 最后登录时间
            }
        }
    
    错误码：
        401: 用户未登录
        500: 服务器错误
    """
    try:
        if request.user.is_authenticated:
            return success_response({
                'id': request.user.id,
                'username': request.user.username,
                'email': request.user.email,
                'first_name': request.user.first_name,
                'last_name': request.user.last_name,
                'is_staff': request.user.is_staff,
                'is_superuser': request.user.is_superuser,
                'date_joined': request.user.date_joined.strftime('%Y-%m-%d %H:%M:%S'),
                'last_login': request.user.last_login.strftime('%Y-%m-%d %H:%M:%S') if request.user.last_login else None
            })
        else:
            return error_response('用户未登录', 401)
    except Exception as e:
        return error_response(f'获取用户信息失败: {str(e)}', 500)


@extend_schema(
    summary="用户注册",
    description="创建新用户账号并自动登录，注册成功后会自动保持登录状态",
    auth=[],  # 注册接口不需要认证
    request={
        "application/json": {
            "type": "object",
            "required": ["username", "password"],
            "properties": {
                "username": {
                    "type": "string",
                    "description": "用户名，必须唯一，只能包含字母、数字和下划线",
                    "example": "newuser"
                },
                "password": {
                    "type": "string",
                    "description": "登录密码，建议使用6位以上复杂密码",
                    "format": "password",
                    "example": "password123"
                },
                "email": {
                    "type": "string",
                    "description": "邮箱地址（可选），用于找回密码和接收通知",
                    "format": "email",
                    "example": "user@example.com"
                }
            },
            "example": {
                "username": "newuser",
                "password": "password123",
                "email": "user@example.com"
            }
        }
    },
    responses={
        200: OpenApiResponse(
            description="注册成功，返回新用户信息",
            response={
                "type": "object",
                "properties": {
                    "code": {"type": "integer", "example": 200},
                    "message": {"type": "string", "example": "注册成功"},
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {"type": "integer", "example": 2},
                            "username": {"type": "string", "example": "newuser"},
                            "email": {"type": "string", "example": "user@example.com"}
                        }
                    }
                }
            }
        ),
        400: OpenApiResponse(description="用户名已存在或参数错误"),
    },
    tags=["用户认证"],
    methods=["POST"]
)
@api_view(['POST'])
@authentication_classes([CsrfExemptSessionAuthentication])  # 使用豁免CSRF的Session认证
@permission_classes([AllowAny])  # 允许所有用户访问，不需要认证
def register_view(request):
    """
    用户注册接口
    
    功能说明：
        - 创建新的用户账号
        - 注册成功后自动登录，保持登录状态
    
    请求参数：
        username (str): 用户名，必填，必须唯一
        password (str): 密码，必填
        email (str): 邮箱，可选
    
    返回数据：
        {
            'code': 200,
            'message': '注册成功',
            'data': {
                'id': 用户ID,
                'username': 用户名,
                'email': 邮箱
            }
        }
    
    错误码：
        400: 用户名已存在或参数错误
        500: 服务器错误
    """
    try:
        data = request.data  # 使用DRF的request.data
        username = data.get('username')
        password = data.get('password')
        email = data.get('email', '')
        
        if not username or not password:
            return error_response('用户名和密码不能为空')
        
        # 检查用户是否已存在
        if User.objects.filter(username=username).exists():
            return error_response('用户名已存在')
        
        # 创建用户
        user = User.objects.create_user(
            username=username,
            password=password,
            email=email
        )
        
        # 自动登录
        login(request, user)
        
        return success_response({
            'id': user.id,
            'username': user.username,
            'email': user.email
        }, '注册成功')
        
    except Exception as e:
        return error_response(f'注册失败: {str(e)}', 500)


@extend_schema(
    summary="修改密码",
    description="修改当前已登录用户的登录密码，需要验证旧密码",
    request={
        "application/json": {
            "type": "object",
            "required": ["old_password", "new_password"],
            "properties": {
                "old_password": {
                    "type": "string",
                    "description": "当前登录使用的旧密码，用于验证身份",
                    "format": "password",
                    "example": "oldpass123"
                },
                "new_password": {
                    "type": "string",
                    "description": "要设置的新密码，建议使用6位以上复杂密码",
                    "format": "password",
                    "example": "newpass123"
                }
            },
            "example": {
                "old_password": "oldpass123",
                "new_password": "newpass123"
            }
        }
    },
    responses={
        200: OpenApiResponse(
            description="密码修改成功",
            response={
                "type": "object",
                "properties": {
                    "code": {"type": "integer", "example": 200},
                    "message": {"type": "string", "example": "密码修改成功"},
                    "data": {"type": "null"}
                }
            }
        ),
        400: OpenApiResponse(description="旧密码错误"),
        401: OpenApiResponse(description="用户未登录，请先登录"),
    },
    tags=["用户认证"],
    methods=["POST"]
)
@api_view(['POST'])
@authentication_classes([CsrfExemptSessionAuthentication])  # 使用豁免CSRF的Session认证
def change_password_view(request):
    """
    修改密码接口
    
    功能说明：
        - 修改当前已登录用户的登录密码
        - 需要验证旧密码以确保安全
    
    请求参数：
        old_password (str): 旧密码，必填
        new_password (str): 新密码，必填
    
    返回数据：
        {
            'code': 200,
            'message': '密码修改成功',
            'data': null
        }
    
    错误码：
        400: 旧密码错误
        401: 用户未登录
        500: 服务器错误
    """
    try:
        if not request.user.is_authenticated:
            return error_response('用户未登录', 401)
        
        data = request.data  # 使用DRF的request.data
        old_password = data.get('old_password')
        new_password = data.get('new_password')
        
        if not old_password or not new_password:
            return error_response('旧密码和新密码不能为空')
        
        # 验证旧密码
        if not request.user.check_password(old_password):
            return error_response('旧密码错误')
        
        # 设置新密码
        request.user.set_password(new_password)
        request.user.save()
        
        return success_response(message='密码修改成功')
        
    except Exception as e:
        return error_response(f'修改密码失败: {str(e)}', 500)